#include"BlockQueue.hpp"
#include"Thread.hpp"
#include<iostream>
#include<unistd.h>

using namespace ThreadModule;
const int num = 5;
void Consumer(BlockQueue<int>& bq)
{
    while(true)
    {
        int data;
        bq.Pop(&data);
        std::cout << "Consumer Consum data is : " << data << " addr: " << &bq << std::endl;
        sleep(1);

    }
}
void Productor(BlockQueue<int>& bq)
{
    while(true)
    {
        int cnt = 1;
        while(true)
        {
            bq.Enqueue(cnt);
            std::cout << "Productor product data is : " << cnt << " addr: " << &bq << std::endl;
            cnt++;
        }
    }
}
void StartComm(std::vector<Thread<BlockQueue<int>>>* threads,int i,BlockQueue<int>& bq,func_t<BlockQueue<int>> func)
{
    for(int j = 0; j < i; j++)
    {
        std::string name = "thread-" + std::to_string(j + 1);
        threads->emplace_back(func,bq,name);
        threads->back().Start();
    }
}
void StartProductor(std::vector<Thread<BlockQueue<int>>>* threads,int i,BlockQueue<int>& bq)
{
    StartComm(threads, i, bq, Productor);
}
void StartConsumer(std::vector<Thread<BlockQueue<int>>>* threads,int i,BlockQueue<int>& bq)
{
    StartComm(threads, i, bq, Consumer);
}
void WaitAllTread(std::vector<Thread<BlockQueue<int>>>& threads)
{
    for(auto& thread : threads)
    {
        thread.Join();
    }
}
int main()
{
    BlockQueue<int>*bq = new BlockQueue<int>(num);
    std::vector<Thread<BlockQueue<int>>> threads;
    StartProductor(&threads,5, *bq);
    StartConsumer(&threads,1, *bq);
    WaitAllTread(threads);
    return 0;
}